package com.sunrise.visual.frame.error
{
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.core.Application;
	import mx.events.CloseEvent;
	import mx.managers.PopUpManager;
	import mx.utils.StringUtil;
	
	/**
	 * 管理错误信息
	 * 
	 * <p>正式版的flash player会自动忽略Error，即使在代码里使用throw new Error()抛出错误信息，
	 * 正式版的flash player也不会有任何提示，但此时程序已经出错，运行异常，而用户不会看见任何提示
	 * 信息（Flex4可以统一的处理错误信息，Flex3不提供此功能）。</p>
	 * 
	 * <p>所以，在编程时应该使用try/catch捕捉并处理错误信息，对于需要显示的错误信息，则应该使用
	 * 本类进行提示</p>
	 * */	
	public class ErrorManager
	{
		/**错误信息窗口*/
		private static var _errorWin:ErrorWindow=new ErrorWindow();
		
		/**错误信息窗口是否已经显示*/
		private static var _isShowing:Boolean=false;
		
		/**错误详细信息窗口是否已经显示*/
		private static var _isDetailShowing:Boolean=false;
		
		[Bindable]
		/**存储错误VO对象*/
		private static var _errorVOs:ArrayCollection;
				
		public function ErrorManager()
		{
			addErrorMessage("ErrorManager is Singleton! ",this);
		}
		
		/**添加错误信息VO
		 * <p>调用此方法会自动弹出错误信息窗口，关闭窗口后错误信息会被清除</p>
		 * */
		public static function addErrorVO(error:ErrorVO):void{
			removeAllProgressMessage();
			
			if(_errorVOs==null)
				_errorVOs=new ArrayCollection();
				
			if(error!=null)
				_errorVOs.addItem(error);
			
			//popupAlert();	
			showErrorWindow();
		}
		
		/**添加错误信息
		 * <p>此方法底层会调用addErrorVO()</p>
		 * @param  message 错误信息,如果为空，则调用此方法将直接返回
		 * @param  code 错误代码
		 * @param  detail 错误详情
		 * @param  source 错误来源
		 * */
		 public static function addErrorMessage(message:String,source:Object=null,code:String="0",detail:String=""):void{
		 	if(message==null||""==StringUtil.trim(message))return ;
		 	
		 	var vo:ErrorVO=new ErrorVO();
		 	vo.message=message;
		 	vo.code=code;
		 	vo.detail=detail;
		 	vo.source=source;
		 	addErrorVO(vo);
		 }		
		
		/**添加错误信息
		 * <p>此方法底层会调用addErrorVO()</p>
		 * @param error 错误信息对象
		 * @param source 错误信息来源
		 * */
		public static function addError(error:Error,source:Object=null):void{
			if(error!=null){
				var vo:ErrorVO=new ErrorVO();
				vo.code=error.errorID+"";
				vo.source=source;
				vo.message=error.message;
				vo.detail=error.getStackTrace();
				addErrorVO(vo);	
			}
		}
		
		/**添加EOS错误信息
		 * <p>此方法底层会调用addErrorVO()</p>
		 * @param errors EOS错误信息,必须是以'exceptions'节点开头符合EOS异常信息格式的XML
		 * @param source 错误信息来源
		 * */		
		public static function addEOSExceptions(errors:XML,source:Object=null):void{
			if (errors == null || errors.localName() != "exceptions")
				return;
			
			var excs: XMLList = errors.exception;
			for each (var exc: XML in excs) {
				var vo:ErrorVO=new ErrorVO();
				vo.code = exc.code;
				vo.source = source;
				vo.message = extractExceptionMessage(exc.message[0]);
				vo.detail = exc;
				addErrorVO(vo);
			}							

			function extractExceptionMessage(source: String): String {
				if (source == null)
					return null;
				var index: int = source.indexOf("Message:");
	
				if (index != -1)
					return source.substring(index + 9, source.length);
				return source;
			}						
		}
		
		private static function popupAlert(): void{
			if(!_isDetailShowing&&!_isShowing){
				_isShowing=true;
				Alert.show("错误", "系统异常，请与系统管理员联系", Alert.YES | Alert.NO, Application.application.root,detailHandler);
				/*AlertDialog.show(LanguageSet.getLanguageText("$System-error","错误"),
									LanguageSet.getLanguageText("$System-errorNormalAlert","系统异常，请与系统管理员联系"),AlertDialog.ERROR,
									[1,2],detailHandler,null,[LanguageSet.getLanguageText("$AlertDialog-Ok","确定"),LanguageSet.getLanguageText("$ErrorWindow-detailLabel","详情")],1);					
				*/
			}
			
			function detailHandler(e:CloseEvent):void{
				_isShowing=false;
				if(e.detail==Alert.NO){
					_errorVOs=null;	
				}else if(e.detail==Alert.YES){
					showErrorWindow();
				}				
			}
		}		
		
		/**显示错误信息窗口*/
		private static function showErrorWindow():void{
			if(!_isDetailShowing){
				_isDetailShowing=true;
				_errorWin.errors=_errorVOs;
				_errorWin.closeWinHandler=handleWinClose;
				_errorWin.show();
			}
		}		
		
		/**处理窗口关闭回调函数*/
		private static function handleWinClose(win:ErrorWindow):void{
			PopUpManager.removePopUp(win);
//			ToolsUtil.clearObjectArray(win.errors.source);
			
			win.errors=null;
			_errorVOs=null;
			_isDetailShowing=false;
		}
		
		/**移除进度条消息*/
		private static function removeAllProgressMessage():void{
			/*if(AppContext.enableProgressLockTarget)return ;
			var viwer:ProgressMessageViewer=ProgressMessageViewer.getInstance();
			var messages:Array=MessageManager.getMessageByType(ProgressMessage.TYPE);
			viwer.removeMessages(messages);*/
		}
		
	}
}